﻿using Microsoft.AspNetCore.Identity;

namespace Devonline.Identity;

/// <summary>
/// Store 接口
/// </summary>
/// <typeparam name="TGroup"></typeparam>
/// <typeparam name="TKey"></typeparam>
public interface IIdentityStore<TIdentity, TKey> : IDisposable where TIdentity : class, IIdentity<TKey> where TKey : IEquatable<TKey>
{
    /// <summary>
    /// Finds and returns a TIdentity, if any, who has the specified <paramref name="id"/>.
    /// </summary>
    /// <param name="id">The resource id to search for.</param>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
    /// <returns>
    /// The <see cref="Task"/> that represents the asynchronous operation, containing the resource matching the specified <paramref name="resourceId"/> if it exists.
    /// </returns>
    Task<TIdentity> FindByIdAsync(TKey id, CancellationToken cancellationToken = default);
    /// <summary>
    /// Finds and returns a TIdentity, if any, who has the specified resource name.
    /// </summary>
    /// <param name="name">The resource name to search for.</param>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
    /// <returns>
    /// The <see cref="Task"/> that represents the asynchronous operation, containing the resource matching the specified <paramref name="name"/> if it exists.
    /// </returns>
    Task<TIdentity?> FindByNameAsync(string name, CancellationToken cancellationToken = default);

    /// <summary>
    /// change the identity name
    /// </summary>
    /// <param name="identity">The identity id to change for.</param>
    /// <param name="name">The name to change for.</param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task SetNameAsync(TIdentity identity, string name, CancellationToken cancellationToken = default);
    /// <summary>
    /// change the identity alias
    /// </summary>
    /// <param name="identity">The identity id to change for.</param>
    /// <param name="alias">The alias to change for.</param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task SetAliasAsync(TIdentity identity, string alias, CancellationToken cancellationToken = default);
    /// <summary>
    /// change the identity image
    /// </summary>
    /// <param name="identity">The identity id to change for.</param>
    /// <param name="image">The image to change for.</param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task SetImageAsync(TIdentity identity, string image, CancellationToken cancellationToken = default);
    /// <summary>
    /// change the user AuthorizeType
    /// </summary>
    /// <param name="identity">The identity id to change for.</param>
    /// <param name="authorizeType">The AuthorizeType to change for.</param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task SetAuthorizeTypeAsync(TIdentity identity, AuthorizeType authorizeType, CancellationToken cancellationToken = default);

    /// <summary>
    /// Creates the specified identity in the store.
    /// </summary>
    /// <param name="identity"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<IdentityResult> CreateAsync(TIdentity identity, CancellationToken cancellationToken = default);
    /// <summary>
    /// Updates the specified identity in the store.
    /// </summary>
    /// <param name="identity"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<IdentityResult> UpdateAsync(TIdentity identity, CancellationToken cancellationToken = default);
    /// <summary>
    /// Delete the specified identity from the store.
    /// </summary>
    /// <param name="identity"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<IdentityResult> DeleteAsync(TIdentity identity, CancellationToken cancellationToken = default);
}